<?php
/**
 * @author jonathan <jo.link.noir@gmail.com>
 * @version 1.0: jo_link_noir
 * @date 19-06-2010
 */
class U1_Player extends SW_Player
{
	/** @var PDO*/
	static protected $db = null;

	/** @var U1_Player = null : player venant de $_SESSION*/
	static private $sessionPlayer = null;

	/** @var int : utiliser dans getSession lorsque le joueur est récupéré en session*/
	protected $selectedPlanetEarly = null;

	/** @var stdClass*/
	protected $config = null;


	/**
	 * Initialise l'offset de $_data si celui-ci n'exista pas.
	 * @param mixed $offset|null
	 */
	protected function initOffset($offset)
	{
		if ($offset === U1_Planet::INDEX)
		{
			$planets = new U1_Planet($this);
			self::getInstanceDb();
			foreach (U1_DAO_Planet::selectAll($this->id) as $p)
				$planets->add($p);

			//affecte la planète séléctionnée si le joueur est celui de la session
			if (self::$sessionPlayer === $this)
				$planets->setCurrentId($this->selectedPlanetEarly);

			return $planets;
		}
		return null;
	}

	/**
	 * Récupère le joueur connecter. Arrête le script si inexistant. Inisialise la db et execute U1_Move_Units::processArrived().
	 * @return self
	 */
	static public function getSession()
	{
		if (self::$sessionPlayer)
			return self::$sessionPlayer;

		if (!session_start() || empty($_SESSION) || empty($_SESSION['player']))
		{
			header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['SCRIPT_NAME']).'/../connexion.php');
			exit;
		}

		if (!SW_Race::defined())
			SW_Race::init(U1_Race::getRace());

		U1_Player::getInstanceDb();
		U1_Move_Units::processArrived();
		self::$sessionPlayer = $_SESSION['player'];
		self::$sessionPlayer->purgeOtherPlayer();
		if (self::$sessionPlayer->offsetExists(U1_Planet::INDEX))
			self::$sessionPlayer->offsetGet(U1_Planet::INDEX)->setCurrentId($this->selectedPlanetEarly);
		return self::$sessionPlayer;
	}

	/**
	 * Vérifie si la session à été chargé
	 * @return U1_Player|null
	 */
	static public function getSessionLoad()
	{
		return self::$sessionPlayer;
	}

	/**
	 * @param bool $initSWDAO = true : si true SW_DAO::init(self::$db); est utilisé
	 * @return PDO
	 */
	static public function getInstanceDb($initSWDAO = true)
	{
		static $init = false;

		if (!self::$db)
		{
			try {
				self::$db = get_instance_db();
			} catch (PDOException $e) {
				exit('Connexion échouée : ' . $e->getMessage().'<br />sudo /etc/init.d/mysql start');
			}
		}

		if (!$init)
		{
			if ($initSWDAO)
			{
				SW_DAO::setDb(self::$db);
				$init = true;
			}
			else
				self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		}

		return self::$db;
	}

	/**
	 * Transforme les données en array pour être utilisé dans serialize
	 * @return array
	 */
	protected function toArray()
	{
		$a = parent::toArray();
		$a['planetCurrentId'] = $this->data->offsetExists(SW_Planet::INDEX)
			? $this->data->offsetGet(SW_Planet::INDEX)->getCurrentId()
			: null;
		$a['config'] = null;///TODO $this->config;
		return $a;
	}

	/**
	 * Utilise le constructeur pour crée un player
	 */
	protected function toPlayer(array $data)
	{
		parent::toPlayer($data);
		$this->selectedPlanetEarly = $data['planetCurrentId'];
		$this->config = $data['config'];
	}

	/**
	 * @param string $section
	 * @param string $key
	 * @param mixed $default = null
	 * @return mixed
	 */
	public function getOption($section, $key, $default = null)
	{
		$config = $this->getConfig();
		return (isset($config->$section) && isset($config->$section->$key))
			? $config->$section->$key
			: $default;
	}

	/**
	 * @return stdClass
	 */
	public function getConfig()
	{
		if (!$this->config)
		{
			$file = DIR_PLAYER.'options/'.$this->id.'.json';
			if (!(
					file_exists($file)
				 && ($file = file_get_contents($file))
				 && ($this->config = json_decode($file))
			))
				$this->config = new stdClass;
		}

		return $this->config;
	}

	public function saveConfig()
	{
		if ($this->config)
			file_put_contents(DIR_PLAYER.'options/'.$this->id.'.json', json_encode($this->config));
	}


	/** @var array : {instance => {id_planet => {SW_Structure_List, …}, …}, …}*/
	private $completedLists = array();

	/** @var bool*/
	private $completedListsIsload = false;

	/** @var bool*/
	private $completedListsloadIsEmpty = true;


	private function loadCompletedLists()
	{
		if ($this->completedListsIsload)
			return;

		$file = DIR_PLAYER.'completedLists/'.$this->id;
		if (file_exists($file))
		{
			$contents = file_get_contents($file);
			unlink($file);
			$this->completedListsloadIsEmpty = false;
			foreach (unserialize($contents) as $structure_index => $planets_lists)
			{
				$lists_structure = &$this->completedLists[$structure_index];
				foreach ($planets_lists as $id_planet => $lists)
				{
					$lists_planet = &$lists_structure[$id_planet];
					foreach ($lists as $id => $list)
					{
						$lists_planet[$id] = $list;
					}
				}
			}
		}
		else
			$this->completedListsloadIsEmpty = true;

		$this->completedListsIsload = true;
	}

	private function resetCompletLists()
	{
		$this->completedListsloadIsEmpty = $this->completedListsIsload = false;
		$this->completedLists = array();
	}


	public function addFinishElement(SW_Structure $structure, SW_Structure_List $list)
	{
		$this->completedLists[$structure::INDEX][$structure->getIdPlanet()][] = $list;
	}

	public function getCompletedLists()
	{
		$this->loadCompletedLists();
		$tmp = $this->completedLists;
		$this->resetCompletLists();
		return $tmp;
	}

	public function &getRefCompletedLists()
	{
		$this->loadCompletedLists();
		return $this->completedLists;
	}

	public function saveCompletedLists()
	{
		$this->loadCompletedLists();
		$empty = empty($this->completedLists);
		if (!$empty && $this->completedListsloadIsEmpty != $empty)
			file_put_contents(DIR_PLAYER.'completedLists/'.$this->id, serialize($this->completedLists));
		$this->resetCompletLists();
	}

	public function __destruct()
	{
		$this->saveCompletedLists();
		parent::__destruct();
	}
}